package orm

import (
	"fmt"
	"strings"
)

// 逻辑条件
type Cond interface {
	// 逻辑反
	Not() Cond
	// 生成SQL
	Gen(args *[]interface{}, param func() string, colname func(string) string) string
}

// AND条件
type condAnd struct {
	cs []Cond
}

// OR过滤器
type condOr struct {
	cs []Cond
}

// ID过滤器
func Id(x interface{}) Cond {
	return Eq("Id", x)
}

// AND
func And(cs ...Cond) Cond {
	return &condAnd{
		cs: cs,
	}
}

// OR
func Or(cs ...Cond) Cond {
	return &condOr{
		cs: cs,
	}
}

func (c *condAnd) Not() Cond {
	n := len(c.cs)
	cs := make([]Cond, n)
	for i := 0; i < n; i++ {
		cs[i] = c.cs[i].Not()
	}
	return Or(cs...)
}

func (c *condOr) Not() Cond {
	n := len(c.cs)
	cs := make([]Cond, n)
	for i := 0; i < n; i++ {
		cs[i] = c.cs[i].Not()
	}
	return And(cs...)
}

func (c *condAnd) Gen(args *[]interface{}, param func() string, colname func(string) string) string {
	n := len(c.cs)
	xs := make([]string, n)
	for i := 0; i < n; i++ {
		xs[i] = fmt.Sprintf("(%v)", c.cs[i].Gen(args, param, colname))
	}
	return strings.Join(xs, " AND ")
}

func (c *condOr) Gen(args *[]interface{}, param func() string, colname func(string) string) string {
	n := len(c.cs)
	xs := make([]string, n)
	for i := 0; i < n; i++ {
		xs[i] = fmt.Sprintf("(%v)", c.cs[i].Gen(args, param, colname))
	}
	return strings.Join(xs, " OR ")
}
